<?php

namespace App\Jobs;

use App\Models\InvestmentMeeting;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use ZipArchive;

class ZipJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(public InvestmentMeeting $meeting)
    {
        //
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        // 生成zip
        InvestmentMeeting::where('id', $this->meeting->id)->update([
            'zip_status' => 2,
            'zip_path' => '',
        ]);
        $folderPath = storage_path('app' . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'invite' . DIRECTORY_SEPARATOR . $this->meeting->title . '_' . $this->meeting->id);
        $zipFileName = storage_path('app' . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'invite' . DIRECTORY_SEPARATOR . $this->meeting->title . '_' . $this->meeting->id . '.zip');
        @unlink($zipFileName);
        $zip = new ZipArchive();
        if (!$zip->open($zipFileName, ZipArchive::CREATE)) {
            InvestmentMeeting::where('id', $this->meeting->id)->update([
                'zip_status' => -1,
            ]);
        }
        $this->addFolderToZip($folderPath, $zip);
        $zip->close();
        InvestmentMeeting::where('id', $this->meeting->id)->update([
            'zip_status' => 1,
            'zip_path' => 'storage/invite/' . $this->meeting->title . '_' . $this->meeting->id . '.zip',
        ]);
        Log::info('生成邀请函及手卡压缩包', ['data' => $this->meeting->id]);
    }

    private function addFolderToZip($folder, $zip)
    {
        $handler = opendir($folder);
        while (($file = readdir($handler)) !== false) {
            if ($file != "." && $file != "..") {
                $path = $folder . DIRECTORY_SEPARATOR . $file;
                $folders = explode(DIRECTORY_SEPARATOR, $folder);
                if (is_dir($path)) {
                    $zip->addEmptyDir($file);
                    $this->addFolderToZip($path, $zip);
                } else if (is_file($path)) {
                    $zip->addFile($path, $folders[count($folders) - 1] . DIRECTORY_SEPARATOR . $file);
                }
            }
        }
        closedir($handler);
    }
}
